package com.zdw.oauth.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdw.common.exception.GlobalException;
import com.zdw.oauth.config.international.InternationalUtils;
import com.zdw.oauth.dto.DepartmentAddDto;
import com.zdw.oauth.dto.DepartmentSelectDto;
import com.zdw.oauth.dto.DepartmentUpdDto;
import com.zdw.oauth.dto.UserDepartmentDto;
import com.zdw.oauth.entity.DepartmentEntity;
import com.zdw.oauth.entity.UserDepartmentEntity;
import com.zdw.oauth.mapper.DepartmentMapper;
import com.zdw.oauth.mapper.UserDepartmentMapper;
import com.zdw.oauth.service.DepartmentService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 部门 服务实现类
 * </p>
 *
 * @author 卓德文
 * @since 2023-07-25
 */
@Service
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, DepartmentEntity> implements DepartmentService {

    @Resource
    private UserDepartmentMapper userDepartmentMapper;

    /**
     * 新增部门
     *
     * @param dto
     * @return
     */
    @Override
    public boolean add(DepartmentAddDto dto) {
        //1.根据部门额编码或部门名称查询部门
        DepartmentEntity entity = this.selectByCodeOrName(dto.getCode(), dto.getName(), null);
        if (ObjectUtil.isNotEmpty(entity) && StrUtil.isNotBlank(entity.getCode())) {
            throw new GlobalException(InternationalUtils.getInternational("department.exist"));
        }

        //2.新增
        DepartmentEntity departmentEntity = BeanUtil.copyProperties(dto, DepartmentEntity.class);
        Integer loginId = Integer.parseInt(StpUtil.getTokenInfo().getLoginId().toString());
        Date date = new Date();
        departmentEntity.setCreator(loginId);
        departmentEntity.setModifier(loginId);
        departmentEntity.setCreateTime(date);
        departmentEntity.setUpdateTime(date);
        return this.baseMapper.insert(departmentEntity) > 0;
    }

    /**
     * 编辑部门
     *
     * @param dto
     * @return
     */
    @Override
    public boolean update(DepartmentUpdDto dto) {
        //1.根据部门额编码或部门名称查询部门
        DepartmentEntity entity = this.selectByCodeOrName(dto.getCode(), dto.getName(), dto.getId());
        if (ObjectUtil.isNotEmpty(entity) && StrUtil.isNotBlank(entity.getCode())) {
            throw new GlobalException(InternationalUtils.getInternational("department.exist"));
        }

        //2.编辑
        DepartmentEntity departmentEntity = BeanUtil.copyProperties(dto, DepartmentEntity.class);
        departmentEntity.setModifier(Integer.parseInt(StpUtil.getTokenInfo().getLoginId().toString()));
        departmentEntity.setUpdateTime(new Date());
        return this.baseMapper.updateById(departmentEntity) > 0;
    }

    /**
     * 删除部门(批量)
     *
     * @param roleIdList
     * @return
     */
    @Override
    public boolean delete(List<Integer> roleIdList) {
        //1.删除部门
        Wrapper<DepartmentEntity> roleWrapper = Wrappers.lambdaQuery(DepartmentEntity.class).in(DepartmentEntity::getId, roleIdList);
        int delCount = this.baseMapper.delete(roleWrapper);

        if (delCount > 0) {
            //2.删除用户-部门的关联关系
            Wrapper<UserDepartmentEntity> userDepartmentWrapper = Wrappers.lambdaQuery(UserDepartmentEntity.class)
                    .in(UserDepartmentEntity::getDepartmentId, roleIdList);
            userDepartmentMapper.delete(userDepartmentWrapper);

            //3.删除子部门--暂不删除
        }
        return delCount > 0;
    }

    /**
     * 查询部门信息
     *
     * @param id
     * @return
     */
    @Override
    public DepartmentEntity select(int id) {
        return this.baseMapper.selectById(id);
    }

    /**
     * 分页查询部门列表
     *
     * @param dto
     * @return
     */
    @Override
    public IPage<DepartmentEntity> page(DepartmentSelectDto dto) {
        IPage<DepartmentEntity> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        Wrapper<DepartmentEntity> wrapper = Wrappers.lambdaQuery(DepartmentEntity.class)
                .eq(StrUtil.isNotBlank(dto.getCode()), DepartmentEntity::getCode, dto.getCode())
                .like(StrUtil.isNotBlank(dto.getName()), DepartmentEntity::getName, dto.getName())
                .eq(ObjectUtil.isNotNull(dto.getParentId()), DepartmentEntity::getParentId, dto.getParentId())
                .eq(ObjectUtil.isNotNull(dto.getState()), DepartmentEntity::getState, dto.getState());
        return this.baseMapper.selectPage(page, wrapper);
    }

    /**
     * 查询部门树
     *
     * @return
     */
    @Override
    public List<DepartmentEntity> tree() {
        return this.baseMapper.tree();
    }

    /**
     * 给用户分配部门
     *
     * @param dto
     * @return
     */
    @Override
    public Boolean grantDepartment(UserDepartmentDto dto) {
        int loginId = Integer.parseInt(StpUtil.getTokenInfo().getLoginId().toString());

        //1.查询传参进来的所有部门下的所有子部门
        List<DepartmentEntity> departmentList = this.baseMapper.selectSonListByIdList(dto.getDepartmentIdList());

        //2.子部门集合去重,并取出其中的ID集合
        List<Integer> idList = departmentList.stream().map(x -> x.getId()).distinct().collect(Collectors.toList());

        //3.所有部门ID集合=上级部门ID集合+子部门ID集合
        List<Integer> collectList = dto.getDepartmentIdList().stream().distinct().collect(Collectors.toList());
        collectList.addAll(idList);

        //4.先删除用户之前的"用户-部门"关联关系
        int deleteCount = userDepartmentMapper.deleteUserDepartmentByUserId(dto.getUserId());

        //5.批量新增"用户-部门"关联关系
        if (deleteCount > 0) {
            return userDepartmentMapper.saveUserDepartmentList(dto.getUserId(), loginId, collectList) > 0;
        }

        return deleteCount > 0;
    }

    /**
     * 根据部门编码或部门名称查询部门
     *
     * @return
     */
    private DepartmentEntity selectByCodeOrName(String code, String name, Integer id) {
        LambdaQueryWrapper<DepartmentEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(StrUtil.isNotBlank(code), DepartmentEntity::getCode, code)
                .or()
                .eq(StrUtil.isNotBlank(name), DepartmentEntity::getName, name)
                .ne(ObjectUtil.isNotEmpty(id), DepartmentEntity::getId, id)
                .last(" limit 1");
        return this.baseMapper.selectOne(queryWrapper);
    }

}
